/*******************************************************************************
 * Copyright 2011 Andrea Guitto
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.andreaguitto.mobile.android.framework.base.object.task;

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.util.Log;

import com.andreaguitto.mobile.android.framework.base.object.activity.AGActivity;

/**
 * 
 * @author napkind
 *
 * @param <param> Parameters to pass onDoWork
 * @param <progress> Parameters to pass onDoWork
 * @param <result>
 */
public class AGAsyncWorkTask<param, progress,result> extends AsyncTask<param, progress, result> {

	protected AGActivity activity;
	
	protected volatile boolean running = true;	
	protected boolean workStopped = false;
	
	public boolean isRunning() {	return running;	}

    private ProgressDialog progressDialog;
    public ProgressDialog getProgressDialog() {	return progressDialog;	}
	public void setProgressDialog(ProgressDialog progressDialog) {	this.progressDialog = progressDialog;	}

	public AGAsyncWorkTask(AGActivity activity, ProgressDialog progressDialog) {
    	this.activity = activity;
        this.progressDialog = progressDialog;
    }
	
	@Override
	protected void onPreExecute(){
		Log.d(getLogTag(), "onPreExecute()");
		
    	if(progressDialog!=null){	       
	    	progressDialog.show();        
    	}
    	running = true;
		
	}
	
	/**
	 * Beta test method
	 * Don't override this method, override instead onDoSingleWork(index, param)
	 * 
	 * @param index
	 * @param param
	 * @throws InterruptedException
	 */	
	
	@Override
	@Deprecated
	protected result doInBackground(param... arg0) {
		Log.d(getLogTag(), "doInBackground()");
		try {
			/*
			for(int i=0; i<arg0.length; i++){
				interruptablePoint("automatic stop at work index "+i);
					onDoSingleWork(i, arg0[i]);
			}
			*/
			return onDoSingleWork(0, arg0[0]);
		}	catch (InterruptedException e) {
			e.printStackTrace();
			workStopped=true;
		}
		return null;
	}
	
	@Override
    protected void onProgressUpdate(progress... progress) {
		Log.d(getLogTag(), "onProgressUpdate()");
    }

	
	@Override
    protected void onPostExecute(result arg) {
		Log.d(getLogTag(), "onPostExecute()");

    	if(progressDialog!=null && progressDialog.isShowing()){
    		progressDialog.dismiss();
    	}
    	
    	if(workStopped){
    		onStopped();
    		return;
    	}
    }	
	
	protected String getLogTag(){
		return this.getClass().getName();
	}
		
	/**
	 * Beta test method
	 * Simplify concept of async task multiple works passed by parameters
	 * with method execute(params1, params2, ecc.. ecc...)
	 * 
	 * to put a breakpoint where async task could be interrupted on stopTask() 
	 * use interruptablePoint(pointDescription);
	 * 
	 * @param index
	 * @param param
	 * @throws InterruptedException
	 */
	public result onDoSingleWork(int index, param param) throws InterruptedException{
		Log.d(getLogTag(), "onDoSingleWork() "+index);
		if(isCancelled()) running = false;
		interruptablePoint("Interrupted before start new work with index "+index);
		return null;
	}

	public final void cancel(){
		cancel(false);
	}
	
	@Override
	protected void onCancelled(){
		if(getProgressDialog()!=null && getProgressDialog().isShowing()){
			getProgressDialog().dismiss();
		}
	}
	
	public void onStopped(){
		Log.d(getLogTag(), "onStopped()");
	}
	
    public final void interruptablePoint(String pointDescription) throws InterruptedException{
    	if(!running)
    		throw new InterruptedException(pointDescription);
    }	


}
